﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Spider.Common.Http;
using Spider.DataAccess.Stock;
using Spider.Models.Stock;
using Spider.Common;
using Spider.Common.Enums;
using System.Threading;

namespace Spider.Business.Stock
{
    public class NoticeBusiness : ISpider
    {
        NoticeDataAccess noticeDataAccess = new NoticeDataAccess();
        StockCompanyDataAccess companyDataAccess = new StockCompanyDataAccess();
        UrlDataAccess urlDataAccess = new UrlDataAccess();
        // 是否中止下载
        private ProcessState state ;
        private int maxThread = 10;    // 最大线程数
        private object objLock = new object();
        public int listIndex = 0; // 结果集数据索引

        public event UILogEventHandler SyncLog;

        /// <summary>
        /// 同步UI 消息
        /// </summary>
        /// <param name="state"></param>
        /// <param name="message"></param>
        private void SyncUILog(ProcessState state, string message)
        {
            if (SyncLog != null)
            {
                SyncLog(state, message);
            }
        }

        public void SpiderNoticeData(object objData)
        {
            if (state == ProcessState.Abort || state == ProcessState.Complete) return;
            if (objData == null) return;

            //List<StockCompanyModel> companies = companyDataAccess.GetAllCompanies();
            ThreadData threadData = (ThreadData)objData;
            if (threadData == null || threadData.Companies == null || threadData.Companies.Count == 0)
                return;
            HttpHelper helper = new HttpHelper();
            List<NoticeModel> noticeModels = new List<NoticeModel>();
            

            while (true)
            {
                if (state == ProcessState.Abort || state == ProcessState.Complete) break;

                lock (objLock)
                {
                    if (listIndex >= threadData.Companies.Count)
                    {
                        break;
                    }
                    var company = threadData.Companies[listIndex];
                    listIndex++;
                    SyncUILog(ProcessState.Processing, string.Format("开始下载 {0}【{1}】的分红公告信息...-- {2}", company.CompanyName, company.StockCode, listIndex));
                    var filterModels = GetData(threadData.UrlModel.Url, company);
                    if (filterModels == null) continue;

                    // 写入数据库
                    noticeDataAccess.AddNotices(filterModels);
                }
            }

            if (state != ProcessState.Complete)
            {
                state = ProcessState.Complete;
                SyncUILog(ProcessState.Complete, "完成分红公告信息下载!");
                urlDataAccess.UpdateUrlState(threadData.UrlModel.UrlId, (int)ProcessState.Complete);
            }

            #region 同步下载数据方法
            
            //foreach (StockCompanyModel company in threadData.Companies)
            //{
            //HttpItem item = new HttpItem()
            //{
            //    URL = string.Format(threadData.Url, company.StockCode),
            //    ContentType = "json"
            //};
            //string jsonData = helper.GetHtml(item);
            //if (jsonData.Contains("Error")) continue;

            //string newString = jsonData.Substring(jsonData.IndexOf('=') + 2).TrimEnd(')');
            //noticeModels = JsonConvert.DeserializeObject<List<NoticeModel>>(newString);
            //var filterModels = noticeModels.Where(e =>
            //{
            //    if (e.Title.Contains("登记日"))
            //    {
            //        e.StockCode = company.StockCode;
            //        return true;
            //    }
            //    return false;
            //}).ToList();
            //if (filterModels.Count > 0)
            //{
            //    noticeDataAccess.AddNotices(filterModels);
            //}
            //}
            #endregion
        }

        /// <summary>
        /// 由新浪网上下载数据 过滤出包含“登记日”信息的消息，并入库
        /// </summary>
        /// <param name="url"></param>
        /// <param name="company"></param>
        /// <returns></returns>
        private List<NoticeModel> GetData(string url, StockCompanyModel company)
        {
            HttpItem item = new HttpItem()
            {
                URL = string.Format(url, company.StockCode),
                ContentType = "json"
            };
            string jsonData = new HttpHelper().GetHtml(item);
            if (jsonData.ToLower().Contains("error")) return null;

            string newString = jsonData.Substring(jsonData.IndexOf("=(") + 2).TrimEnd(')');
            var noticeModels = JsonConvert.DeserializeObject<List<NoticeModel>>(newString);
            if (noticeModels == null || noticeModels.Count == 0)
            {
                return null;
            }
            var filterModels = noticeModels.Where(e =>
            {
                if (e.Title.Contains("登记日"))
                {
                    e.StockCode = company.StockCode;
                    return true;
                }
                return false;
            }).ToList();
            if (filterModels.Count > 0)
            {
                noticeDataAccess.AddNotices(filterModels);
            }

            return filterModels;
        }

        public void SpiderData(object urlModel)
        {
            try
            {
                state = ProcessState.Processing;
                List<StockCompanyModel> companies = companyDataAccess.GetAllCompanies();
                int companyCount = companies.Count;
                Thread thread = new Thread(delegate()
                {
                    while (true)
                    {
                        if (state == ProcessState.Abort)
                        {
                            SyncUILog(ProcessState.Abort, "用户中止下载!");
                            return;
                        }
                        if (state == ProcessState.Complete)
                        {
                            SyncUILog(ProcessState.Abort, "下载完成!");
                            return;
                        }

                        int threadCount = maxThread;
                        if (companyCount > 0 && companyCount < maxThread)
                        {
                            threadCount = companyCount;
                        }
                        SyncUILog(ProcessState.Start, string.Format("开启{0}个线程下载数据！",threadCount));
                        //文本日志

                        ThreadData paramData = new ThreadData()
                        {
                            UrlModel =(SourceUrlModel)urlModel,
                            Companies = companies
                        };

                        urlDataAccess.UpdateUrlState(paramData.UrlModel.UrlId, (int)ProcessState.Processing);

                        //开启多线程
                        Thread[] arrThread = new Thread[threadCount];
                        for (int i = 0; i < threadCount; i++)
                        {
                            arrThread[i] = new Thread(new ParameterizedThreadStart(SpiderNoticeData));
                            arrThread[i].IsBackground = true;
                            arrThread[i].Start(paramData);
                        }

                        for (int i = 0; i < threadCount; i++)
                        {
                            if (arrThread[i] != null && arrThread[i].IsAlive)
                            {
                                arrThread[i].Join();
                            }
                        }
                    }
                });

                thread.IsBackground = true;
                thread.Start();
            }
            catch (Exception e)
            {

                throw e;
            }
        }

        class ThreadData
        {
            public SourceUrlModel UrlModel { get; set; }

            public List<StockCompanyModel> Companies { get; set; }
        }

        /// <summary>
        /// 中止下载
        /// </summary>
        public void SpiderAbort()
        {
            state = ProcessState.Abort;
            SyncUILog(ProcessState.Abort, "用户中止下载数据!");
        }

        public List<NoticeModel> GetLastNotices()
        {
            return noticeDataAccess.GetLastNotices();
        }
    }
}
